package com.weizhu.swufer.testconsumer.controller;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.weizhu.swufer.api.demo.DemoService;
import com.weizhu.swufer.constant.SwuferConstant;
import com.weizhu.swufer.core.annotation.SwuferReference;
import com.weizhu.swufer.core.client.GenericService;
import com.weizhu.swufer.core.rpc.RpcContext;
import com.weizhu.swufer.core.exception.RpcException;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

@RestController
public class ConsumerController {

    @SwuferReference(failBackMockService = "demoMockService")
    DemoService demoService;

    @SwuferReference()
    GenericService genericService;


    private static final int nThread = 30;//Runtime.getRuntime().availableProcessors() * 2

    private static final ExecutorService pool = Executors.newFixedThreadPool(nThread);

    @RequestMapping("test/hello")
    public String testSync(@RequestParam("name") String name) throws ExecutionException, InterruptedException {
        RpcContext.getContext().setParameter("version",1.0);
        RpcContext.getContext().setParameter(SwuferConstant.TOKEN,"123456");
        return demoService.hello(name);
    }

    @RequestMapping("test/async")
    public String testAsync(@RequestParam("name") String name) throws Exception{
        try {
            demoService.hello(name);
            ListenableFuture<String> listenableFuture = RpcContext.getContext().getListenableFuture();
            Futures.addCallback(listenableFuture, new FutureCallback<String>() {
                @Override
                public void onSuccess(@Nullable String s) {
                    System.out.println(s+"async");
                }

                @Override
                public void onFailure(Throwable throwable) {
                    throwable.printStackTrace();
                }
            },pool);

            return listenableFuture.get();
        }catch (RpcException e){

            return e.getCode() + e.getMessage();
        }
    }

    @RequestMapping("test/noargs")
    public String testNoArgMethod(){
        try {
            return demoService.testNoArgMethod();
        }catch (RpcException e){

            return e.getCode() + e.getMessage();
        }
    }

    @RequestMapping("test/multi")
    public String testMulti(@RequestParam("name") String name){
        try {
            Map<String,Object> map = new HashMap();
            map.put("name",name);
            return demoService.testMultiArgs(name,map);
        }catch (RpcException e){

            return e.getCode() + e.getMessage();
        }
    }

    @RequestMapping("test/generic")
    public String testGeneric(@RequestParam("name") String name){
        try {
            return (String) genericService.$invoke("com.weizhu.swufer.api.demo.DemoService","hello",
                    "generic_test");
        }catch (Exception e){

            return e.getMessage();
        }
    }

}
